from pyrfid.ApplicationInterface.ApplicationCommand import ApplicationCommand
from pyrfid.ApplicationInterface.argument import *

from pyrfid.asn1.Encoder import Encoder
from pyrfid.asn1.Decoder import Decoder
import time
import sys
from pyrfid.ApplicationInterface.argument.WriteResponses import WriteResponses

class WriteObjectsSegmentedMemoryTagCommand(ApplicationCommand):
    
    
    
    """docstring for WriteObjectSegmentedMemoryCommand"""
    def __init__(self, tagId, memoryBank, accessPassword, AFI, DSFID, addObjectsList):
        print "WriteObjectsSegmentedMemoryTagCommand"
        # 
        # if memoryBank == ApplicationCommand.USER and AFI != '':
        #     raise 'AFI is not needed. AFI need for UII'
        # 
        self.COMMAND_MODULE_OID = '28FC597E12'
        self.RESPONSE_MODULE_OID = '28FC597F12'
        self.TAG_ID = tagId
        self.MEMORY_BANK = memoryBank
        self.ACCESS_PASSWORD = accessPassword
        self.AFI = AFI
        self.DSFID = DSFID
        self.ADD_OBJECTS_LIST = addObjectsList    
        self.listCmdAndData = []
        self.ENCODED_COMMAND = ''
    
    def encode(self):
        """docstring for encode"""
        if self.ENCODED_COMMAND != '':
            return self.ENCODED_COMMAND
        
        encoder = Encoder()
        
        self.listCmdAndData.append(['06', '05', self.COMMAND_MODULE_OID])
        self.listCmdAndData.append(['30', '', ''])
        
        #tagID
        tagIdHex = encoder.octetStrEncode(self.TAG_ID)
        lenTagIDHex = encoder.lengthEncode(len(tagIdHex) / 2)
        self.listCmdAndData.append([self.OCTET_STRING, lenTagIDHex, tagIdHex])
        
        #memoryBank
        memoryBankHex = encoder.octetStrEncode(self.MEMORY_BANK)
        lenMemoryBankHex = encoder.lengthEncode(len(memoryBankHex) / 2)
        self.listCmdAndData.append([self.OCTET_STRING, lenMemoryBankHex, memoryBankHex])
                
        #accessPassword
        accessPasswordHex = encoder.octetStrEncode(self.ACCESS_PASSWORD)
        lenAccessPasswordHex = encoder.lengthEncode(len(accessPasswordHex) / 2)
        self.listCmdAndData.append([self.OCTET_STRING, lenAccessPasswordHex, accessPasswordHex])
        
        #AFI(Application Family ID)
        self.listCmdAndData.append([self.INTEGER, '01', encoder.intEncode(self.AFI.APPLICATION_FAMILY)])
        self.listCmdAndData.append([self.INTEGER, '01', encoder.intEncode(self.AFI.APPLICATION_SUB_FAMILY)])
        
        #DSFID(DSFID)
        self.listCmdAndData.append([self.INTEGER, '01', encoder.intEncode(self.DSFID.ACCESS_METHOD)])
        
        dataFormatLengthHex = encoder.lengthEncode(len(str(encoder.intEncode(self.DSFID.DATA_FORMAT))) / 2)
        self.listCmdAndData.append([self.INTEGER, dataFormatLengthHex, encoder.intEncode(self.DSFID.DATA_FORMAT)])
        
        #for addObjectsList
        self.listCmdAndData.append(['30','', ''])
        addObjectLength = 0
        for addObject in self.ADD_OBJECTS_LIST:
            #OBJECT_IDENTIFIER(OBJECT IDENTIFIER)
            objectIdentifier = encoder.oidEncode(addObject.OBJECT_IDENTIFIER)
            lenOIDHex = encoder.lengthEncode(len(objectIdentifier) / 2)
            self.listCmdAndData.append([self.OBJECT_IDENTIFIER, lenOIDHex, objectIdentifier])
            addObjectLength += int(lenOIDHex, 16)
            
            #AVOID_DUPLICATE(BOOLEAN)
            self.listCmdAndData.append([self.BOOLEAN, '01', encoder.boolEncode(addObject.AVOID_DUPLICATE)])
            addObjectLength += 1
            
            #OBJECT(OCTET STRING)
            objectHex = encoder.octetStrEncode(addObject.OBJECT)
            lenObjHex = encoder.lengthEncode(len(objectHex) / 2)
            self.listCmdAndData.append([self.OCTET_STRING, lenObjHex, objectHex])
            addObjectLength += int(lenObjHex, 16)
            
            #COMPACT PARAMETER(INTEGER)
            self.listCmdAndData.append([self.INTEGER, '01', encoder.intEncode(addObject.COMPACT_PARAMETER)])
            addObjectLength += 1
            
            #OBJECT LOCK(BOOLEAN)
            self.listCmdAndData.append([self.BOOLEAN, '01', encoder.boolEncode(addObject.OBJECT_LOCK)])
            addObjectLength += 1
        
        #for TL : set length
        self.listCmdAndData[9][1] = str(encoder.lengthEncode(addObjectLength))
        self.listCmdAndData[1][1] = str(encoder.lengthEncode(int(lenTagIDHex, 16) + 1 + int(lenAccessPasswordHex, 16) + 1 + 1 + addObjectLength ))
        
        self._convertToHexString()
        return self.ENCODED_COMMAND
        
    def decode(self, encodedRSP):
        """docstring for decode"""
        print encodedRSP
 
        decoder = Decoder(encodedRSP)
        encoder = Encoder()
        
        print "----"
        print decoder
        print "----"
        encoder.oidEncode(decoder.popElement().VALUE)
        # sys.exit()
        # if encoder.oidEncode(decoder.popElement().VALUE) != self.RESPONSE_MODULE_OID:
        #     raise "ERROR"
        
        #pop 30
        decoder.popElement()
                
        #objects:SEQUENCE OF SEQUENCE
        decoder.popElement()
        
        dataSetArray = []
        writeResponseList = []
        length = decoder.getLengthElement() - 2
        for index in range(length / 2):
            
            #objectId:OBJECT_IDENTIFIER
            objectIdentifier = decoder.popElement().VALUE
            completionCode = decoder.popElement().VALUE
            writeResponseList.append(WriteResponses(objectIdentifier, completionCode));
        
        
        #completion code:INTEGER
        self.completionCode = decoder.popElement().VALUE
        #execution code:INTEGER
        self.executionCode = decoder.popElement().VALUE
                    
        return {'WriteCompletionList':writeResponseList ,'CompletionCode':self.completionCode, 'ExecutionCode':self.completionCode}
        
    
if __name__ == '__main__':
    tagId = "E200C0D2B25FD380"
    memoryBank = ApplicationCommand.USER
    accessPassword = "unko"
    AFI = ApplicationFamilyId(1, 2)

    DSFID = DSFID(0, 9)
    
    objectIdentifier1 = '1 0 15961 9 1'
    avoidDuplicate = False 
    objectValue = 'AB12XY'
    compactParameter = 1 
    objectLock = False
    addObject1 = AddObjects(objectIdentifier1, avoidDuplicate, objectValue, compactParameter, objectLock)

     
    objectIdentifier2 = '1 0 15961 9 31'
    avoidDuplicate = False
    #time stamp is YYMMDDHHMM
    objectValue  = 'RFID.'
    #time.strftime("%y%m%d%H%M",time.localtime(time.time()))
    #object = "NARUHODO"
    addObject2 = AddObjects(objectIdentifier2, avoidDuplicate, objectValue, compactParameter, objectLock)
    
    objectIdentifier3 = '1 0 15961 9 33'
    objectValue = 'Hello'
    addObject3 = AddObjects(objectIdentifier3, avoidDuplicate, objectValue, compactParameter, objectLock)
    
    objectIdentifier4 = '1 0 15961 9 34'
    objectValue = 'hamutarou'
    addObject4 = AddObjects(objectIdentifier4, avoidDuplicate, objectValue, compactParameter, objectLock)
    
    
    addObjectList = []
    addObjectList.append(addObject1) 
    #addObjectList.append(addObject2)
    #addObjectList.append(addObject3)
    #addObjectList.append(addObject4)
    # #     
    command = WriteObjectsSegmentedMemoryTagCommand(tagId, memoryBank, accessPassword, AFI, DSFID, addObjectList)
    
    print 'Command is ',command.encode()
    #print command.decode('060528FC597F13302B3029060728FC5909832501040D31323334353637383930313233020101010100060728FC5909B65B01040A30383132323131373533020101010100020100020100')